/**
 * Copyright (c), 上海沃恩信息科技有限公司.
 * All rights reserved.
 * Licensed under BSD (https://www.pittypat.work/bsd.html).
 */

package pittypat.web;

import java.io.IOException;
import java.io.Writer;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import pittypat.IJson;
import pittypat.Json;

/**
 * 要发送给客户端的二进制内容。
 */
public final class ByteArray implements IJson {
	private byte[] content;
	private String fileName;
	private String contentType;

	private static final byte[] EMPTY_CONTENT = new byte[0];

	/**
	 * 使用二进制数据、文件名称、文件类型初始化 BinaryContent 的新实例。
	 */
	public ByteArray(byte[] content, String fileName, String contentType) {
		this.content = content == null ? EMPTY_CONTENT : content;
		this.fileName = fileName == null ? "" : fileName;
		this.contentType = contentType == null || contentType.length() == 0 ? Mime.of(Path.getExtension(this.fileName))
				: contentType;
	}

	/**
	 * 使用二进制数据、文件名称初始化 Binary 的新实例。
	 */
	public ByteArray(byte[] content, String fileName) {
		this(content, fileName, null);
	}

	/**
	 * 将当前对象作为 JSON 字符串写入指定的文本流。
	 * 
	 * @param writer
	 *            目标文本流。
	 * @throws IllegalArgumentException
	 *             writer 是 null。
	 * @throws IOException
	 * @see pittypat.Model#write(java.io.Writer)
	 */
	@Override
	public void write(Writer writer) throws IOException {
		Json.write(writer, this.content);
	}

	/**
	 * 获取二进制内容。
	 * 
	 * @return 二进制内容。
	 */
	public byte[] getContent() {
		return this.content;
	}

	/**
	 * 获取文件的名称。
	 * 
	 * @return 文件名称。
	 */
	public String getFileName() {
		return this.fileName;
	}

	/**
	 * 获取文件的 MIME 类型。
	 * 
	 * @return MIME 类型。
	 */
	public String getContentType() {
		return this.contentType;
	}

	/**
	 * 通过指定的响应对象发送二进制内容。
	 * 
	 * @param response
	 *            响应。
	 * @throws IOException
	 */
	public void send(HttpServletResponse response) throws IOException {
		if (response == null) {
			return;
		}

		response.setContentLengthLong(this.content.length);
		response.setContentType(this.contentType);
		response.setHeader("Content-Disposition", "attachment; filename=" + this.fileName);

		// 响应输出流
		ServletOutputStream outStream = response.getOutputStream();
		// 将数组内容写入目标流
		outStream.write(this.content, 0, this.content.length);
	}
}
